package com.douqu.game.core.util;

import com.bean.agent.JavaAgent;
import com.bean.core.util.Utils;
import com.douqu.game.core.factory.LoadFactory;
import com.douqu.game.core.util.cls.ClassReader;

import java.io.File;
import java.io.InputStream;
import java.lang.instrument.ClassDefinition;

/**
 * @Author: Bean
 * @Description:
 * @Date: 2018-08-06 19:21
 */
public class HotUpdateUtils {

    public final static String PATH = "hot/";

    public static File checkDirectory(String path)
    {
        //热更新服务器,只能修改方法内部的逻辑,不能修改方法名,方法参数类型,个数,也不能添加删除方法,服务器重启时请记得重新打新的包

        File file = new File(CoreUtils.getBasePath() + path);

        return file.exists() && file.isDirectory() ? file : null;
    }

    private static void updateClassByPath(String clsPath, String excludeClassName)
    {
        try {
            if(!clsPath.endsWith(".class"))
            {
                LogUtils.error("Update Class Error -> " + clsPath);
                return;
            }

            if(JavaAgent.INST != null)
            {
                InputStream is = LoadFactory.getInputStream(clsPath);
                byte[] array = new byte[is.available()];
                is.read(array);
                is.close();

                String className = ClassReader.getClassName(clsPath);
                if(!Utils.isNullOrEmpty(excludeClassName) && className.indexOf(excludeClassName) != -1)
                {
                    LogUtils.warn("不更新此类 -> " + className);
                }
                else
                {
                    LogUtils.info("Update Class -> " + className);
                    Class cls = Class.forName(className);
                    JavaAgent.INST.redefineClasses(new ClassDefinition(cls, array));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void updateClass(File file, String excludeClassName)
    {
        try{
            if(file.isFile())
            {
                LogUtils.warn("Update Class -> " + file.getName());
                updateClassByPath(file.getAbsolutePath(), excludeClassName);
            }
            else
            {
                File[] files = file.listFiles();
                for(File f : files)
                {
                    LogUtils.warn("Update Class -> " + f.getName());
                    updateClassByPath(f.getAbsolutePath(), excludeClassName);
                }
            }
            Thread.sleep(1000);

        }catch (Exception e){
            e.printStackTrace();
        }

    }


//    public static void updateClassAbsolute(String clsPath, String clsName)
//    {
//        try {
//            if(JavaAgent.INST != null)
//            {
//                FileInputStream is = new FileInputStream(clsPath);
//                byte[] array = new byte[is.available()];
//                is.read(array);
//                is.close();
//                Class cls = Class.forName(clsName);
//                JavaAgent.INST.redefineClasses(new ClassDefinition(cls,array));
//            }
//            Thread.sleep(1000);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }



}
